unity ugui性能优化: 找到引起网格重建的具体ui元素

您所在的位置:网站首页 unity ugui drawcall unity ugui性能优化: 找到引起网格重建的具体ui元素

unity ugui性能优化: 找到引起网格重建的具体ui元素

#unity ugui性能优化: 找到引起网格重建的具体ui元素| 来源: 网络整理| 查看: 265

通常UGUI界面操作卡大概率都是Canvas.SendWillRenderCanvases()方法耗时,需要检查界面是否存在多余或者无用的重建情况。由于界面很多我们无法定位到到底是哪个界面下的哪个元素引起了网格重建。 通过观察CanvasUpdateRegistry.cs源代码,我们发现需要网格重建的元素都被缓存在这两个对象中。

// CanvasUpdateRegistry.cs(部分代码) public class CanvasUpdateRegistry { //...略 //保存待重建布局元素(如:RectTransform变化) private readonly IndexedSet m_LayoutRebuildQueue = new IndexedSet(); //保存待重建渲染元素(如:Image变化) private readonly IndexedSet m_GraphicRebuildQueue = new IndexedSet(); }

我们来看看待重建布局元素和待重建渲染元素是如何被缓存起来的。如果某个Graphic发生布局位置或者渲染变化会分别加入这两个不同的渲染队列,等待下一次UI的重建。

// Graphic cs(部分代码 public abstract class Graphic: UIBehaviour,ICanvasElement { //...略 protected override void OnBeforeTransformParentChanged() { GraphicRegistry.UnregisterGraphicForCanvas(canvas, this); //布局发生变化 LayoutRebuilder.MarkLayoutForRebuild(rectTransform); //LayoutRebuilder.MarkLayoutForRebuild方法内部实现 //private static void MarkLayoutRootForRebuild(RectTransform controller) //{ // if (controller == null) // return; // var rebuilder = s_Rebuilders.Get(); // rebuilder.Initialize(controller); // 局部发生变化,会通过TryRegisterCanvasElementForLayoutRebuild()将自己加入待布局重建队列 // if (!CanvasUpdateRegistry.TryRegisterCanvasElementForLayoutRebuild(rebuilder)) // s_Rebuilders.Release(rebuilder); //} } public virtual void SetMaterialDirty() { if (!IsActive()) return; m_MaterialDirty = true; //渲染发生变化,会通过RegisterCanvasElementForGraphicRebuild()将自己加入待渲染队列 CanvasUpdateRegistry.RegisterCanvasElementForGraphicRebuild(this); if (m_OnDirtyMaterialCallback != null) m_OnDirtyMaterialCallback(); } }

所以我们只需要在外面将这两个对象捞出来遍历一下就能知道到底是哪个界面下的哪个元素引起了网格重建。

using System.Collections.Generic; using System.Reflection; using UnityEngine; using UnityEngine.UI; public class NewBehaviourScript : MonoBehaviour { IList m_LayoutRebuildQueue; IList m_GraphicRebuildQueue; private void Awake() { System.Type type = typeof(CanvasUpdateRegistry); FieldInfo field = type.GetField("m_LayoutRebuildQueue", BindingFlags.NonPublic | BindingFlags.Instance); m_LayoutRebuildQueue = (IList)field.GetValue(CanvasUpdateRegistry.instance); field = type.GetField("m_GraphicRebuildQueue", BindingFlags.NonPublic | BindingFlags.Instance); m_GraphicRebuildQueue = (IList)field.GetValue(CanvasUpdateRegistry.instance); } private void Update() { for (int j = 0; j


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3